<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="test"></div>
    <script src="./js/17.0.1/react.development.js"></script>
    <script src="./js/17.0.1/react-dom.development.js"></script>
    <script src="./js/17.0.1/babel.min.js"></script>
    <script type="text/babel">
    /*
        1.初始化阶段：由ReactDOM.render()触发---初次渲染
            1.constructor()
            2.getDerivedStateFromProps()
            3.⭐render()
            4.componentDidMount()
        2.更新阶段：由组件内部this.setState()或父组件重新render触发
            1.getDerivedStateFromProps()
            2.shouldComponentUpdate()
            3.render()
            4.getSnapshotBeforeUpdate()
            5.⭐compentDidUpdate()
        3.卸载组件：由ReactDOM.unmountComponentAtNode()触发
            1.⭐componentWillUnmount()
        
    */ 
        class Test extends React.Component {
            // 构造器
            constructor(props) {
                console.log('count------constructor')
                super(props)
            }
            // 初始化状态
            state = {count:0}
            add = ()=>{
                let {count} = this.state
                count++
                this.setState({count})
            }
            upDate = ()=>{
                this.forceUpdate()
            }
            remove = ()=>{
                ReactDom.unmountComponentAtNode(document.getElementById('test'))
            }
            // getDerivedStateFromProps钩子替换了所有的将要更新的钩子函数，这个方法必须写成静态方法，
            //                          而且该函数必须有返回值，返回值需要为一个state对象或者null,返回值可以修改状态，但是
            static getDerivedStateFromProps(props,state){
                console.log('count------getDerivedStateFromState',props,state)
                return null
            }
            // 组件挂载完毕的钩子
            componentDidMount(){
                console.log('count------compentDidMount')
            }
            /*
                使用setState()的时候，会执行阀门、执行将要更新、执行更新完成
                使用forceUpdate()的时候，会执行将要更新、更新完成               //forceUpdate强制更新，不更改状态强制更新内容,无论阀门是否开启
            */ 
            // 控制组件更新的阀门的钩子
            // 返回值为true的话可以通过，返回值为false的话不可以通过，如果没写默认帮你写为true
            shouldComponentUpdate(){
                console.log('count------shouldComponentUpdate')
                return true
            }
             // 在数据渲染前最后一次执行的函数,在DOM发生更改之前获取一些内容
            getSnapshotBeforeUpdate(){
                console.log('count------getSnapshotBeforeUpdate')
                return 'wzc'
            }
            // 组件更新完成后的钩子,有两个参数第一个参数是之前的props，第二个参数是之前的state,第三个参数就是快照值
            componentDidUpdate(preProps,preState,snapshotValue){
                console.log('count------componentDidUpdate')
            }
            // 组件卸载的钩子
            componentWillUnmount(){
                console.log('count------componentWillUnmount')
            }
            render() { 
                console.log('count------render')
                const {count} = this.state
                return  (
                    <div>
                        <h2>当前求和为{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.upDate}>组件强制更新</button>
                        <button onClick={this.remove}>卸载组件</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Test  count={199}/>, document.getElementById("test"))
    </script>
</body>
</html>